<template>
  <div style="padding: 20px">
    <!-- 头部 -->
    <div class="header">
      <div style="width: 30%; display: flex; align-items: center">
        <div style="width: 120px">角色名称:</div>
        <el-input v-model="pageData.keyword" />
      </div>
      <div class="buttons">
        <el-button @click="getList">搜索</el-button>
        <el-button @click="reSet">重置</el-button>
        <el-button @click="addClick">新增</el-button>
      </div>
    </div>
    <!-- 表格 -->
    <el-table max-height="520" :data="list" border style="width: 100%">
      <el-table-column
        fixed
        type="index"
        label="#"
        width="100"
        align="center"
      />
      <el-table-column label="id" width="120" prop="id" align="center" />
      <el-table-column
        label="角色名称"
        width="220"
        prop="name"
        align="center"
      />
      <el-table-column label="描述" width="200" prop="desc" align="center" />
      <el-table-column label="创建时间" prop="created_at" align="center" />
      <el-table-column label="更新时间" prop="updated_at" align="center" />
      <!-- 操作 -->
      <el-table-column label="操作" align="center">
        <template slot-scope="scope">
          <div style="display: flex; justify-content: space-evenly">
            <el-button
              @click="editThis(scope.row)"
              type="primary"
              icon="el-icon-edit"
              circle
            ></el-button>
            <el-button
              @click="setpermissionShow(scope.row)"
              type="warning"
              icon="el-icon-star-off"
              circle
            ></el-button>
            <el-button
              @click="deleThis(scope.row.id)"
              type="danger"
              icon="el-icon-delete"
              circle
            ></el-button>
          </div>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页器 -->
    <div class="foot">
      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="pageData.page"
        :page-sizes="[10, 15, 20]"
        :page-size="pageData.limit"
        layout="total, sizes, prev, pager, next, jumper"
        :total="count"
      >
      </el-pagination>
    </div>
    <!-- 新增和编辑公用的弹窗 -->
    <el-dialog
      :title="isEdit ? '编辑角色' : '新增角色'"
      :visible.sync="dialogFormVisible"
      width="50%"
    >
      <el-form :rules="rules" ref="adminForm" status-icon :model="adminForm">
        <el-form-item label="角色" prop="name">
          <el-input v-model="adminForm.name" />
        </el-form-item>
        <el-form-item label="备注" prop="desc">
          <el-input v-model="adminForm.desc" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="sub">确 定</el-button>
      </div>
    </el-dialog>
    <!-- 分配权限 -->
    <el-dialog custom-class="permission" :visible.sync="permissionShow">
      <div slot="title" class="permission_title">
        <span>分配权限</span>
      </div>
      <!-- 一旦默认选中的话 就一直是固定值了 随弹窗消失树形控件一起消失-->
      <el-tree
        v-if="permissionShow"
        :data="data"
        ref="tree"
        show-checkbox
        node-key="id"
        :default-checked-keys="permissionId"
        :props="defaultProps"
        check-strictly
      />
      <div slot="footer" class="dialog-footer">
        <el-button @click="permissionShow = false">取 消</el-button>
        <el-button type="primary" @click="subpermission">确定</el-button>
      </div>
    </el-dialog>
  </div>
</template>
    
<script>
import { listPermission } from "@/api/permission";
import {
  listRole,
  addRole,
  editRole,
  deleteRole,
  addRolePermission,
  deleteRolePermission,
} from "@/api/role";
export default {
  name: "RoleManagement",
  data() {
    return {
      list: [], //表格数据
      pageData: {
        limit: 10,
        page: 1,
        keyword: "",
      },
      isEdit: false, //判断新增还是添加的字段
      count: 0, //总条数
      dialogFormVisible: false, //新增和编辑表单的显隐
      adminForm: {
        //表单数据
        name: "",
        desc: "",
      },
      rules: {
        name: [{ required: true, trigger: "blur", message: "请输入角色" }],
        desc: [{ required: true, trigger: "blur", message: "请输入备注" }],
      },
      permissionShow: false, //分配权限弹窗显隐
      //树形控件数据
      data: [],
      defaultProps: {
        children: "children",
        label: "name",
      },
      permissionId: [], //默认选中的id 数组
      roleId: "", //添加权限的角色id
    };
  },
  methods: {
    //获取表格数据
    async getList() {
      let res = await listRole(this.pageData);
      let { data } = res;
      this.list = data.list;
      this.count = data.count;
    },
    //重置
    reSet() {
      this.pageData.keyword = "";
      this.getList();
    },
    //每页条数变化
    handleSizeChange(size) {
      this.pageData.limit = size;
      this.getList();
    },
    //当前页发生变化
    handleCurrentChange(page) {
      this.pageData.page = page;
      this.getList();
    },
    //删除数据
    deleThis(id) {
      this.$confirm("此操作将永久删除该角色, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(async () => {
          await deleteRole({ id });
          this.$message({
            type: "success",
            message: "删除成功!",
          });
          this.getList();
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消删除",
          });
        });
    },
    //添加和编辑角色
    sub() {
      this.$refs.adminForm.validate(async (valid) => {
        if (valid) {
          if (this.isEdit) {
            //编辑
            await editRole(this.adminForm);
            this.$message({
              message: "编辑成功",
              type: "success",
            });
          } else {
            //添加
            await addRole(this.adminForm);
            this.$message({
              message: "成功添加",
              type: "success",
            });
          }
          this.dialogFormVisible = false;
          this.getList(); //刷新列表
        }
      });
    },
    //点击编辑按钮
    editThis(row) {
      this.isEdit = true;
      this.dialogFormVisible = true;
      this.adminForm = {
        //数据回显
        name: row.name,
        desc: row.desc,
        id: row.id,
      };
    },
    // 点击新增按钮
    addClick() {
      this.isEdit = false;
      this.dialogFormVisible = true;
    },
    //点击按钮权限弹窗显示
    setpermissionShow(row) {
      this.permissionShow = true;
      //权限数据回显 默认选择id的数组
      this.permissionId = (row.permissions || []).map((item) => item.id);
      this.roleId = row.id; //给当前要添加权限的id赋值
    },
    //编辑权限
    async subpermission() {
      //编辑流程  先删除原本有的权限 再添加选中的权限!!!
      // this.$refs.tree.getCheckedKeys() 返回目前被选中的节点的 key 所组成的数组
      //删除本来有的权限  数组大于0才调接口
      if(this.permissionId.length){
        await deleteRolePermission({role_id:this.roleId,permission_ids:this.permissionId})
      }
      //添加权限 数组大于0才调接口
      if(this.$refs.tree.getCheckedKeys().length){
        await addRolePermission({role_id: this.roleId,permission_ids: this.$refs.tree.getCheckedKeys()});
      }
      this.$message({
        message: "编辑权限成功",
        type: "success",
      });
      this.permissionShow=false;
      this.getList();
    },
  },
  created() {
    this.getList();
  },
  async mounted() {
    //获取权限列表数据
    let { data } = await listPermission({ limit: 100, page: 1 });
    let arr = data.list.map((item) => {
      //一级路由的实现
      if (item.path.split("/").length === 2) {
        //过滤出一级路由下的二级路由
        let childrenArr = data.list.filter((item1) => {
          return (
            item1.path.split("/").length == 3 &&
            item1.path.split("/")[1] == item.path.split("/")[1]
          );
        });
        return {
          ...item,
          children: childrenArr,
        };
      }
    });
    //后端返回的数据改造成组件需要的树状结构
    this.data = arr.filter((item) => item);
  },
  //监听
  watch: {
    dialogFormVisible() {
      //变为false时清空表单数据
      if (!this.dialogFormVisible) {
        this.adminForm = {
          name: "",
          desc: "",
        };
      }
    },
  },
};
</script>
    
<style scoped lang="scss">
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.foot {
  margin-top: 10px;
  float: right;
}
.permission {
  .dialog-footer {
    text-align: center;
  }
  .permission_title {
    text-align: center;
  }
}
</style>